package com.rtx.edi.platform.quartz.service.impl;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rtx.api.annotation.RtxJobAnnotation;
import com.rtx.edi.platform.quartz.bean.JobEntity;
import com.rtx.edi.platform.quartz.mapper.JobMapper;
import com.rtx.edi.platform.quartz.service.JobService;

/**
 * 定时任务
 */
@Service
public class JobServiceImpl implements JobService {

    @Autowired
    private JobMapper jobMapper;

    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;

    @Override
    public void add(JobEntity jobEntity) throws Exception{
        Class<?> jobClass = Class.forName(jobEntity.getJobClassName());
        String jobName = jobEntity.getJobName();
        
        
        String description = jobEntity.getDescription();
        String cron = jobEntity.getCronExpression();
        String trigger = jobName + "Trigger";
        String group = jobEntity.getJobGroup();
        boolean exists = schedulerFactoryBean.getScheduler().checkExists(new JobKey(jobName, group));
        if(!exists){
            JobDetail jobDetail = JobBuilder
                    .newJob((Class<? extends Job>) jobClass)
                    .withIdentity(jobName, group)
                    .withDescription(description)
                    .usingJobData("apiMappingCode",jobEntity.getApiMappingCode())
                    .build();
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
            CronTrigger cronTrigger = TriggerBuilder
                    .newTrigger()
                    .withIdentity(trigger, group)
                    .withDescription(description)
                    .withSchedule(scheduleBuilder)
                    .build();
            schedulerFactoryBean.getScheduler().scheduleJob(jobDetail,cronTrigger);
        }else{
            throw new RuntimeException("任务：" + jobName + "已存在" + group + "分组中");
        }
    }
    
    /**
     * 新增时 验证当前调度任务,是否需要配置对接场景编码
     * @param jobEntity
     */
    private void checkJobApiMappingCode(RtxJobAnnotation jobAnnotation,JobEntity jobEntity) {
    	if(jobAnnotation.needMappingCode()) {
    		if(!StringUtils.hasLength(jobEntity.getApiMappingCode())) {
    			throw new RuntimeException("当前调度任务需配置对接场景编码，请选择合适的对接场景编码！");
    		}
    	}
    }

    @Override
    public void delete(JobEntity jobEntity) throws Exception {
        String jobName = jobEntity.getJobName();
        String jobGroup = jobEntity.getJobGroup();
        schedulerFactoryBean.getScheduler().pauseTrigger(TriggerKey.triggerKey(jobName,jobGroup));
        schedulerFactoryBean.getScheduler().unscheduleJob(TriggerKey.triggerKey(jobName,jobGroup));
        schedulerFactoryBean.getScheduler().deleteJob(JobKey.jobKey(jobName, jobGroup));
    }

    @Override
    public void update(JobEntity jobEntity) throws Exception {
    	 String triggerName = jobEntity.getTriggerName();
         String triggerGroup = jobEntity.getTriggerGroup();
         TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroup);
    	CronScheduleBuilder builder = CronScheduleBuilder.cronSchedule(jobEntity.getCronExpression());
    	CronTrigger trigger = (CronTrigger) schedulerFactoryBean.getScheduler().getTrigger(triggerKey);


    	// 按新的cronExpression表达式重新构建trigger
    	trigger = trigger.getTriggerBuilder()
    			.withIdentity(triggerName, triggerGroup)
    			.withSchedule(builder)
    			.build();
    	// 按新的trigger重新设置job执行
    	schedulerFactoryBean.getScheduler().rescheduleJob(triggerKey, trigger);
    }

    @Override
    public void execute(JobEntity jobEntity) throws Exception {
        String jobName = jobEntity.getJobName();
        String jobGroup = jobEntity.getJobGroup();
        schedulerFactoryBean.getScheduler().triggerJob(JobKey.jobKey(jobName, jobGroup));
    }

    @Override
    public void pause(JobEntity jobEntity) throws Exception {
        String jobName = jobEntity.getJobName();
        String jobGroup = jobEntity.getJobGroup();
        schedulerFactoryBean.getScheduler().pauseJob(JobKey.jobKey(jobName, jobGroup));
    }

    @Override
    public void resume(JobEntity jobEntity) throws Exception {
        String jobName = jobEntity.getJobName();
        String jobGroup = jobEntity.getJobGroup();
        schedulerFactoryBean.getScheduler().resumeJob(JobKey.jobKey(jobName, jobGroup));
    }

    @Override
    public void pageList(Page<JobEntity> pageParam, JobEntity jobEntity) {
        pageParam.setRecords(jobMapper.pageList(pageParam, jobEntity.getDescription()));
    }
}
